CHAPTER 12
Connection Methods and Security
Most of the chapters in this book focus on describing the high-level XMPP protocols
in terms of stanzas sent and received, without talking about the XML streaming layer
that  handles  the  sending  and  receiving  of  stanzas  over  the  wire.  To  round  out  our
coverage of XMPP, we focus on the lower layers of the XMPP protocol stack in this
chapter.
XMPP provides a great deal of flexibility regarding connection methods, authentication, encryption, and other fundamentals. This chapter walks you through some of
these fundamentals, showing how you can use them to build more powerful and secure
applications.  First,  we  describe  standard  client-to-server  connections  over  TCP,  including techniques for securing those connections. We then illustrate the power of the
network by explaining how server-to-server connections work, and how servers can be
extended using external components. We then look at an alternative binding that enables you to send XMPP traffic over HTTP for web applications and for mobile devices
that have intermittent network connectivity. Going even farther afield, we explore how
to set up serverless messaging between clients on ad-hoc local networks. Finally, we
provide an overview of some of the key security issues to consider when deploying
XMPP-based systems.
Negotiating an XMPP Stream
The fundamental building block of XMPP is the XML stream, which in client-to-server
communication equates to a session. A client session starts by connecting to a server
and negotiating the session details, after which the client can send message, presence,
and IQ stanzas to other entities on the network. The session ends when the client (or
the server) decides to close the stream. In this section, we focus on how the client and
server work together to set up the XML stream; what happens after that is the topic of
the other chapters in Part II.
165
In broad outline, setting up a client-to-server session consists of the following phases:
1. Initiating a TCP connection to the server
2. Opening an XML stream
3. Negotiating various stream features
4. Authenticating with the server
5. Selecting a resource
6. For IM applications, requesting the roster and sending initial presence
After  the  session  has  been  started,  the  actual  XMPP  communication  (consisting  of
message, IQ, and presence stanzas) can start happening.
Let’s say that our friend alice@wonderland.lit wants to connect to her server. She first
needs to find out which physical machine is providing XMPP services for that domain.
You might expect that Alice can simply connect to the machine wonderland.lit. However, XMPP allows you to run your XMPP service for a given domain on any host you
choose, so this guess isn’t necessarily correct (although it’s a good fallback method).
To find out the machine name of the XMPP service for wonderland.lit, Alice needs to
do a DNS Service lookup. This means that she queries the DNS SRV record for the
_xmpp-client._tcp.wonderland.lit. service (i.e., the machine that services XMPP clients over TCP at the wonderland.lit domain). The DNS answer yields the following
result:
_xmpp-client._tcp.wonderland.lit. 86400 IN SRV 10 20 5222 xmpp1.wonderland.lit 
_xmpp-client._tcp.wonderland.lit. 86400 IN SRV 10 5 5222 xmpp2.wonderland.lit
It  seems  that  there  are  two  XMPP  servers  available  for  the  wonderland.lit  service,
xmpp1 and xmpp2, and that both of them are running on port 5222 (which is the standard
port  used  for  receiving  XMPP  client  connections).  To  proceed,  Alice’s  does  the
following:
1. Based on the priority and weight of the records, picks one of these machines (here,
2. Performs a standard “A” (or “AAAA”) lookup to determine the IP address of the
xmpp1.wonderland.lit).
chosen machine.
3. Opens a TCP connection to that IP address and port.
Now the XMPP negotiation begins. Alice’s client sends an initial stream header to the
server:
<?xml version="1.0"?>
<stream:stream
               version="1.0"
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
 to="wonderland.lit"
166 | Chapter 12: Connection Methods and Security
This is the XML text declaration. It is optional to include it before sending the stream
header itself.
Elements qualified by the http://etherx.jabber.org/streams namespace must always be prefixed with stream: (e.g., an opening stream tag of <stream:stream>).
The to attribute contains the domain part of Alice’s JID. It is the logical domain
name, which might not be the same as the physical machine used for connecting.
The version attribute indicates the version of the XMPP protocol. This is always 1.0.
The xmlns attribute specifies the default namespace for all XML sent over the stream
(i.e., the namespace that applies if no other namespace is noted). Because this is a
client-to-server stream, the default namespace is jabber:client.
The <stream/> element is not closed. At this point the client sends only the opening
tag to start the stream, i.e., <stream:stream>. From now on, all subsequent XML
elements will be sent as children of this root element, until the session ends by closing
the root element with the ending </stream:stream> tag.
In response, the server opens a response stream in the opposite direction by sending an
opening  <stream:stream>  tag  to  Alice  (as  mentioned,  there  is  one  stream  in  each
direction):
<?xml version="1.0"?>
<stream:stream from="wonderland.lit"
               id="k0d1m43rt53ht"
               version="1.0" 
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
Before sending the response stream header, the server generates a unique stream ID
for this session.
Immediately after opening the response stream, the server tries to reach agreement with
the client on how the connection will proceed. First, the server tells the client about
the stream features it supports:
<stream:features>
  <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
    <optional/>
  </starttls>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>PLAIN</mechanism>
    <mechanism>DIGEST-MD5</mechanism>
    <required/>
  </mechanisms>
  <compression xmlns="http://jabber.org/features/compress">
    <method>zlib</method>
  </compression>
</stream:features>
Negotiating an XMPP Stream | 167
In this case, the server supports the following features:
• Encrypted connections with the XMPP profile of Transport Layer Security (TLS)
[RFC 5246]. The wonderland.lit server says that TLS negotiation is optional, but
in general it is recommended for all XML streams (we discuss TLS in “Encrypting
the Connection” on page 172).
• Authentication  via  the  Simple  Authentication  and  Security  Layer  (SASL)  [RFC
4422].  In  this  case,  the  only  supported  authentication  methods  are  the  PLAIN
mechanism  and  the  DIGEST-MD5  mechanism.  The  wonderland.lit  server  says
that SASL negotiation is required.
• Stream  compression  for  more  optimal  bandwidth  usage,  as  described  in
[XEP-0138]; this too is optional here (the wonderland.lit server has not included
an <optional/> child element, but features default to optional).
Optional Features
RFC 3920 defined the <required/> flag only for the TLS stream feature,
and did not define the <optional/> flag at all. Implementation experience has indicated the need for consistent flagging of which stream features are required and which are optional, so the document that captures
ongoing revisions to RFC 3920 (known as [rfc3920bis]) specifies that
all stream features must indicate whether they are required or optional.
Because Alice isn’t interested in securing or compressing her connection at this point,
she proceeds directly to the authentication step. In this step, she logs in to her account
by passing her credentials to the server, proving to the server that she really is Alice.
Since the wonderland.lit service supports both DIGEST-MD5 and PLAIN, Alice chooses the simplest alternative, and authenticates herself using the PLAIN mechanism (this
is for demonstration purposes only—don’t do this over an unencrypted connection,
because your password will be sent in the clear!). Alice does this by sending a Base64encoded version of a string containing her username and her password, separated by
a 0 byte:
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">
  AGFsaWNlAHBhc3N3b3JkCg==
</auth>
(The Base64-decoded string is <0>alice<0>password—clearly Alice needs some instruction on best practices for information security.)
Alice’s server responds with the message that her authentication was successful:
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
168 | Chapter 12: Connection Methods and Security
SASL Challenges
Unlike the PLAIN authentication mechanism, most SASL authentication mechanisms typically consist of more than one step. In those cases,
the server and client send each other different subsequent challenges
and responses (embedded in <challenge/> and <response/> elements),
until the authentication has been established.
Immediately following the notification of successful authentication, the server resets
the session by sending a new stream header (with a new Stream ID). This time, however,
it announces different stream features:
<?xml version="1.0"?>
<stream:stream from="wonderland.lit"
               id="d1r3ht0n4"
               version="1.0" 
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
  <stream:features>
    <compression xmlns="http://jabber.org/features/compress">
      <method>zlib</method>
    </compression>
    <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
      <required/>
    </bind>
    <session xmlns="urn:ietf:params:xml:ns:xmpp-session">
      <optional/>
    </session>
  </stream:features>
SASL negotiation has been completed, so the authentication feature is no longer advertised. However, two other features are now included: support for resource binding
and support for formally starting an XMPP session.
Before starting the XMPP session, Alice requests a resource from the server, since this
is necessary for proper routing of XMPP stanzas. Because Alice is currently in the rabbit
hole, she decides to ask for a resource called rabbithole:
The server acknowledges this request, which means that Alice’s full JID on the XMPP
network is now alice@wonderland.lit/rabbithole:
<iq id="b1h4r9rx" type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <resource>rabbithole</resource>
  </bind>
</iq>
<iq id="b1h4r9rx" type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>alice@wonderland.lit/rabbithole</jid>
  </bind>
</iq>
Negotiating an XMPP Stream | 169
Resource Assignment
When a client requests a specific resource, most servers grant the requested resource unchanged if it is available, or fail if it is not. However,
servers are always free to assign a different resource than the one requested.  For  example,  when  requesting  the  rabbithole  resource,  the
server  could  have  returned  alice@wonderland.lit/rabbithole-1  in  its
response, binding the session to the rabbithole-1 resource instead. A
possible reason for doing this is to avoid collisions between resources,
or to randomize resource IDs for security purposes.
Finally, Alice seals the deal by explicitly starting an XMPP session:
<iq id="uyq6z751" type="set">
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</iq>
And the server responds with success:
<iq id="uyq6z751" type="result"/>
The Session No-Op
After the XMPP RFCs were published in October 2004, the XMPP developer community realized that the  xmpp-session step of the stream
negotiation was unnecessary, so most clients and servers now treat it as
a “no-op,” advertise it only for backward compatibility, and proceed
normally if the step is skipped.
Alice can now begin sending messages and presence notifications. She will typically
start by retrieving her roster and sending initial presence, as we discussed in Chapter 3:
<iq from="alice@wonderland.lit/rabbithole"
    id="hr71vl77"
    to="alice@wonderland.lit"
    type="get">
  <query xmlns="jabber:iq:roster"/>
</iq>
<iq from="alice@wonderland.lit"
    id="hr71vl77"
    to="alice@wonderland.lit/rabbithole"
    type="result">
  <query xmlns="jabber:iq:roster">
    <item jid="whiterabbit@wonderland.lit"/>
    <item jid="lory@wonderland.lit"/>
    <item jid="mouse@wonderland.lit"/>
    <item jid="sister@realworld.lit"/>
  </query>
</iq>
<presence/>
170 | Chapter 12: Connection Methods and Security
Now that Alice has logged in, retrieved her roster, and sent initial presence, she can
chat with friends, join chat rooms, and interact with other entities on the network.
Authentication Options
The PLAIN mechanism illustrated in the previous section is the very simplest (and least
secure)  of  SASL  mechanism.  One  benefit  of  the  SASL  framework  is  that  it  enables
application developers and service administrators to support many different authentication mechanisms depending on their requirements. Here are some of the SASL mechanisms that are currently used or planned for deployment within the XMPP community:
PLAIN
DIGEST-MD5
SCRAM
EXTERNAL
GSSAPI
As  we’ve  seen,  the  PLAIN  mechanism  [RFC  4616]  provides  a  very  simple
password-based authentication method. Because the password is sent without any
security protection, the PLAIN mechanism is safe to use only if the underlying XML
stream is protected using Transport Layer Security (TLS).
The  DIGEST-MD5  mechanism  [RFC  2831]  provides  stronger  security  than  the
PLAIN mechanism, since the password is encrypted in transit (thus the channel
does  not  require  TLS  security).  Unfortunately,  many  interoperability  problems
have arisen for DIGEST-MD5, not just in XMPP but in other uses of SASL, such
as IMAP. Therefore, the IETF has deprecated DIGEST-MD5 in favor of SCRAM.
The Salted Challenge Response Authentication Mechanism [SCRAM] is the IETF’s
proposed replacement for DIGEST-MD5. The mechanism provides quite strong
protection against numerous security threats when it is used in conjunction with
Transport Layer Security. Because SCRAM is a new technology (in fact, it had not
yet been published as an RFC at the time of this writing), it will probably take some
time before all XMPP servers support it.
The EXTERNAL mechanism [RFC 4422] enables the initiating entity (whether a
client or a server) to present a digital certificate during TLS negotiation and then
refer to that certificate during authentication, thus obviating the need for passwords altogether. However, very few end users outside of certain specialized environments have digital certificates, so in practice the EXTERNAL mechanism is
used more for server-to-server connections than for client-to-server connections.
The GSSAPI mechanism [RFC 4121] was conceived as a general SASL mechanism
(pluggability within pluggability!), but to date has been employed only for use with
Kerberos V. The GSSAPI mechanism is deployed even less widely than the EXTERNAL mechanism, but is quite powerful within organizations that use Kerberos
for “single sign-on.”
Authentication Options
| 171
ANONYMOUS
The ANONYMOUS mechanism [RFC 4505] enables users to authenticate without
having  registered  accounts  on  the  server.  This  mechanism  is  most  useful  for
customer-facing applications, such as call centers and online help systems, where
it  doesn’t  make  sense  to  require  registration  for  a  one-time  use  of  the  XMPP
application.
Some of these authentication methods can also result in a mutually authenticated session that invokes a security layer, thus providing integrity protection and encryption.
However, this aspect of SASL is not as widely used as its authentication capabilities.
Instead,  as  described  in  the  next  section,  Transport  Layer  Security  is  used  for
encryption.
Encrypting the Connection
Connecting  to  an  XMPP  server  using  a  normal  TCP  connection  (as  you  saw  in  the
previous section) has the disadvantage of not being secure. Indeed, eavesdroppers who
are able to monitor the traffic on your network can intercept everything you send to
your  server,  including  personal  messages,  and  even  the  password  you  send  in  the
authentication step. Clearly this is not good!
The authentication phase can be made more secure by using an authentication mechanism that, unlike PLAIN, does not send your password in a way that it can be reconstructed from the traffic you send (e.g., DIGEST-MD5). Nevertheless, this still leaves
the rest of your communication going over the wire in an unsecured fashion (if, say,
DIGEST-MD5 was not used to negotiate a security layer). Another problem is that you
have no assurance that the server you are connecting to is indeed the server you think
it is. For example, a malicious person can find ways to redirect your connection to his
own host, resulting in you sending your credentials to a server without even noticing
this. However, these problems are not specific to XMPP: the same issues arise when
entering your credit card number on a website, when sending an email with sensitive
company information, and so on. This is why smart security professionals have designed a general solution for securing connections. This solution was originally called
Secure Sockets Layer (SSL) and is now called Transport Layer Security [RFC 5246]. Just
like all the other widely used Internet protocols that employ either SSL or TLS, XMPP
uses TLS for securing its connections as well. This section describes the XMPP profile
of TLS for client-to-server connections.
172 | Chapter 12: Connection Methods and Security
TLS and SSL
Transport  Layer  Security  is  the  IETF’s  evolution  of  Secure  Sockets
Layer. SSL was originally developed by Netscape in the early years of
the Web to encrypt TCP connections between web browsers and web
servers, usually on port 443 (“https”) instead of port 80 (“http”). Originally the Jabber community followed the same convention by encrypting client-to-server TCP connections on port 5223 instead of 5222. With
the publication of [RFC 3920] in 2004, XMPP adopted the more modern
practice of upgrading an unencrypted connection to encrypted using the
<starttls/> command. This means that an ordinary (unsecured) connection is set up first, after which a  <starttls/> command is sent to
negotiate an encrypted connection.
Let’s say that the wonderland.lit server has instituted a new security policy. When Alice
opens a session, the server greets her with the following stream features announcement:
<stream:stream from="wonderland.lit" 
               id="d1r3ht0n4" 
               version="1.0" 
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
  <stream:features>
    <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
      <required/>
    </starttls>
  </stream:features>
Not only does the wonderland.lit server announce support for secure connections using  TLS,  it  even  requires  encrypted  connections.  Indeed,  in  addition  to  the
<required/> tag within the <starttls/> element, the server doesn’t announce support
for any authentication mechanisms, so Alice has no choice but to switch to an encrypted
connection:
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
This request is promptly followed by an acknowledgment from the server:
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
From the point where the <proceed/> happened, the regular XMPP stream ends, and
the TLS handshake starts happening over the TCP connection itself. This handshake
step involves the server sending a certificate to the client, and the client validating the
certificate to ensure that the server is indeed the one it claims to be. This handshake
occurs directly over the TCP connection using standard TLS messages (not an XML
encapsulation of TLS), as defined in the TLS specification. After the handshake has
successfully  completed,  the  client  restarts  its  XMPP  session,  only  now  encrypting
everything it sends using the key received from the server during the TLS handshake:
Encrypting the Connection | 173
<stream:stream to="wonderland.lit" 
               version="1.0"
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
Because the connection is now secure, the server responds with more stream features,
including  authentication  mechanisms,  allowing  the  client  to  start  authenticating  its
XMPP session, as we discussed in the last section:
<stream:stream from="wonderland.lit" 
               id="c8b7rn6p6" 
               version="1.0" 
               xmlns="jabber:client"
               xmlns:stream="http://etherx.jabber.org/streams">
  <stream:features>
    <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
      <mechanism>PLAIN</mechanism>
      <mechanism>DIGEST-MD5</mechanism>
    </mechanisms>
  </stream:features>
Server Federation
So far, the focus of this chapter has been on creating a connection between a client and
a server. However, if you want to send a message to a contact on another server, your
server needs to connect to the other server before it can send the message through. This
kind of server-to-server connectivity is commonly called federation. In this section, we
talk about how federated connections are made, what the security considerations are,
and how these security problems are solved.
c2s and s2s
Client-to-server  connections  are  often  abbreviated  as  c2s  in  the  networking world, whereas server-to-server connections are (not surprisingly) referred to as s2s connections.
Server-to-server (s2s) connections basically follow the same pattern as client-to-server
connections: after opening a connection to the host serving XMPP for the target JID,
the sending server needs to authenticate itself before it is allowed to send a message.
Without authentication, any server would be able to pretend that it is responsible for
a given domain, and could send messages in the name of any user in that domain (this
is called domain spoofing).
Just as in the case of clients connecting to a server, servers can also use SASL to authenticate themselves. The SASL mechanisms most commonly used by clients require
the user to register in some way with the server and then reference the registered credentials when authenticating. This is impractical for server-to-server connections because XMPP promotes a distributed network where servers don’t need to have prior
174 | Chapter 12: Connection Methods and Security
knowledge about each other (this dynamic federation model is similar to email but
different from the formal “peering” model public telecommunication networks use).
You  might  therefore  think  that  SASL  cannot  be  used  for  inter-domain  federation.
However, one SASL mechanism comes in handy here: the EXTERNAL mechanism.
For server-to-server connections, SASL EXTERNAL is used in conjunction with Transport Layer Security. During the TLS negotiation, the servers exchange certificates in
both directions. After the negotiation completes, the servers can then simply refer to
the certificates provided via TLS for mutual authentication. Unfortunately, the use of
TLS and SASL EXTERNAL is not yet widespread, even though it provides strong serverto-server authentication.
In the case where certificate-based verification is not possible, XMPP servers fall back
on the less secure approach of checking the validity of a sending server, called server
dialback. This approach can be illustrated by the story of a representative from your
electric company coming to your house and asking whether he can enter to work on
your electric system. Before letting him into your house, you ask for his employee ID
number. You then call the number of the electric company’s service department (which
you looked up in your own phone book), and ask them whether the employee with the
given ID is allowed to come and work on your house. After having checked their records, the service department confirms that the person at your door is indeed one of
their employees and is authorized to visit you now, so you let him enter. In XMPP, the
equivalent of the homeowner is the receiving server (to which an s2s connection is being
made), the equivalent of the worker is the originating server (which is attempting to
connect), the equivalent of the phone book is the Domain Name System (DNS), and
the equivalent of the service department is the authoritative server for the originating
domain.
The basic flow of events is as follows:
1. The originating server performs a DNS lookup on the hostname of the receiving
server, opens a TCP connection to the discovered IP address and port, and establishes an XML stream with the receiving server.
2. The originating server generates a dialback key and sends that value over its XML
stream with the receiving server.
3. The Receiving Server does not immediately accept the connection but instead performs a DNS lookup on the hostname of the authoritative server, opens a TCP
connection to the discovered IP address and port, and establishes an XML stream
with the authoritative server.
4. The receiving server sends the same dialback key over its XML stream with the
authoritative server for verification.
5. The authoritative server replies that the key is valid or invalid.
6. The receiving server informs the originating server whether its identity has been
verified or not.
Server Federation | 175
This flow is illustrated in Figure 12-1.
Figure 12-1. Server dialback defines a DNS-based “callback” method that provides weak identity
verification
Let’s walk through the case where Alice wants to send a message to her sister in the
real world. In order to get the message delivered, Alice’s server wonderland.lit needs
to open a connection to realworld.lit. A DNS lookup for SRV records for the XMPP
server service at realworld.lit yields the following result:
_xmpp-server._tcp.xmpp.realworld.lit. 86400 IN SRV 10 0 5269 xmpp.realworld.lit
Alice’s  server  therefore  performs  a  standard  “A”  or  “AAAA”  lookup  on  xmpp.real
world.lit to discover that machine’s IP address, opens a TCP connection on port 5269
at that IP address, and starts an XML stream:
<stream:stream from="wonderland.lit" 
               to="realworld.lit" 
               version="1.0"
               xmlns="jabber:server"
               xmlns:db="jabber:server:dialback"
               xmlns:stream="http://etherx.jabber.org/streams">
176 | Chapter 12: Connection Methods and Security
Inclusion of the jabber:server:dialback namespace declaration indicates to the receiving server that the originating server supports the server dialback protocol.
The realworld server sends a response stream header and the stream features:
<stream:stream from="realworld.lit" to="wonderland.lit" id="D60000229F" version="1.0"
        xmlns="jabber:server"
        xmlns:db="jabber:server:dialback"
        xmlns:stream="http://etherx.jabber.org/streams">
  <stream:features>
    <dialback xmlns="urn:xmpp:features:dialback">
      <required/>
    </dialback>
  </stream:features>
The receiving server apparently requires the originating server to provide some verification of its identity using the dialback protocol. To start this verification process, the
wonderland server generates a dialback key, which will be used by the receiving server
and the authoritative server to verify the originating server. This key is then sent to the
realworld server:
<db:result from="wonderland.lit" to="realworld.lit">
 37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:result>
To verify whether the server that opened a connection is really the wonderland server,
the realworld server now “dials back” to the wonderland server. To do that, it looks
up the host serving XMPP for that domain using a DNS SRV query, resulting in the
following reply:
_xmpp-server._tcp.wonderland.lit. 86400 IN SRV 10 0 5269 cm.wonderland.lit
This is the authoritative server for wonderland.lit. The realworld server now performs
a standard “A” or “AAAA” lookup on cm.wonderland.lit to discover that machine’s IP
address, opens a TCP connection on port 5269 at that IP address, and starts an XML
stream:
The cm.wonderland.lit machine in turn replies with the normal stream header:
<stream:stream from="realworld.lit" 
               to="wonderland.lit" 
               version="1.0"
               xmlns="jabber:server"
               xmlns:db="jabber:server:dialback"
               xmlns:stream="http://etherx.jabber.org/streams">
<stream:stream from="wonderland.lit" 
               id="D60000229F"
               to="realworld.lit"
               version="1.0"
               xmlns="jabber:server"
               xmlns:db="jabber:server:dialback"
               xmlns:stream="http://etherx.jabber.org/streams"
  <stream:features>
    <dialback xmlns="urn:xmpp:features:dialback">
Server Federation | 177
      <optional/>
    </dialback>
  </stream:features>
Now that the realworld server has a reverse connection to the wonderland server, it can
ask the latter whether it is trying to connect a stream with the given ID and the given key:
<db:verify from="realworld.lit" to="wonderland.lit" id="D60000229F">
  37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:verify>
The wonderland server confirms that it is indeed trying to connect and that the key
given is valid:
<db:verify from="wonderland.lit" 
           id="D60000229F"
           to="realworld.lit" 
           type="valid">
  37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:verify>
The realworld server is now confident that the stream opened by the originating server
is indeed from a server in the wonderland network, and therefore sends a response on
its initial stream with the originating server, informing the wonderland.lit server that
it may proceed with sending stanzas:
<db:result from="realworld.lit" to="wonderland.lit" type="valid">
  37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:result>
Verification complete!
In the foregoing example, we assumed that the initiating server (the server opening the
connection) was the same as the authoritative server (the server used by the receiving
server to verify the validity of the key). However, this doesn’t always have to be the
case. You can compare this to a self-employed electrician picking up the phone when
you dial his company’s number from the phone book, as opposed to the administration
office of the company answering the phone and validating employees.
Although the server dialback protocol provides a relatively good authenticity check, it
is still weaker than using TLS plus SASL EXTERNAL for this job. The main weakness
of this approach is that it relies on the initiating host being registered through DNS,
which means that DNS poisoning attacks can still result in domain spoofing if the DNS
security extensions (DNSSEC) are not used. This is the major reason why it is preferable
to use certificate-based validation with TLS.
178 | Chapter 12: Connection Methods and Security
Got Certs?
One of the challenges related to TLS is not support for it in software but
the availability of certificates. In the early days, many server administrators  installed  “self-signed”  certificates  that  were  not  issued  by  a
recognized Certification Authority (CA). But such “homegrown” certificates cause security warnings to pop up in XMPP clients—and security
warnings are scary to most end users. Unfortunately, acquiring a certificate that is signed by one of best-known CA’s can cost quite a bit of
money. To remedy this situation, the XMPP Standards Foundation offers  free  certificates  to  administrators  of  XMPP  servers,  currently  by
running an Intermediate CA that uses StartCom (a widely recognized
certification authority) as the root CA. For more information or to obtain a free certificate for your XMPP server, visit http://xmpp.org/ca/.
Server Components
A third class of entities that can connect to an XMPP server, besides clients and other
XMPP servers, is made up of server components. Server components, like MUC components (see Chapter 7), connect to a server and get a specific subdomain of the server
assigned to them (e.g.,  conference.wonderland.lit). Whenever the XMPP server receives a stanza addressed to a JID within this domain, it directly routes the stanza to
the component over the component’s connection with the server.
Setting up a stream between a component and the server is done using a simple handshake protocol, defined in Jabber Component Protocol [XEP-0114]. After having opened
a  connection  to  the  wonderland.lit  server,  our  MUC  component  starts  the  stream,
using the requested subdomain of the component as the to target of the stream:
<stream:stream xmlns="jabber:component:accept"
               xmlns:stream="http://etherx.jabber.org/streams"
               to="conference.wonderland.lit">
The server replies by starting a stream as well:
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" 
               xmlns="jabber:component:accept" 
               from="conference.wonderland.lit" 
               id="3BF96D32">
At this point, the component needs to authenticate itself with the server. This authentication is done by taking a shared secret known by both the server and the component,
and applying a transformation on it. More specifically, the shared secret is appended
to the stream ID of the server stream, after which the value is hashed (using SHA-1)
and  then  Base64-encoded.  The  component  then  sends  the  resulting  string  in  a
<handshake/> element:
<handshake>aaee83c26aeeafcbabeabfcbcd50df997e0a2a1e</handshake>
Server Components
| 179
After the server has verified that our key is indeed what the server expects it to be, it
sends back a successful result:
<handshake/>
After this handshake has completed, the server will send all stanzas addressed to the
conference.wonderland.lit domain over this stream to the component, and the component can send stanzas originating from the same domain over the stream.
Because the existing component protocol lacks some flexibility and does not enable a
component to upgrade the stream to an encrypted connection using Transport Layer
Security, a number of XMPP developers have shown an interest in building a more
modern component protocol. The beginnings of such a protocol are documented in a
proposal called Component Connections [XEP-0225], but further work remains to be
done  before  that  protocol  will  be  ready  for  widespread  implementation  and
deployment.
BOSH: XMPP over HTTP
So far, all of the client-to-server and server-to-server connections we’ve looked at happen over long-lived TCP connections, where the parties keep that connection open as
long as the session is needed. However, in certain situations, it can be difficult or inconvenient to maintain a long-lived TCP connection. The following are some examples:
• Networks with intermittent connectivity can repeatedly interrupt the TCP connection, forcing the client to expend a large number of round trips to frequently
re-establish an XMPP session by negotiating stream headers, encryption, authentication, resource binding, roster retrieval, and initial presence.
• On a mobile phone or other portable devices, constantly maintaining a long-lived
TCP connection can quickly drain the battery.
• Some web-based applications do not carry any state and as such can’t keep a con
nection open.
• Restrictive firewall settings can prevent even a standard XMPP client from opening
a regular TCP connection to an XMPP server.
The solution is to use a connection method that does not require the client to maintain
a long-lived TCP connection. The standard way to do so emulates the bidirectional
streams that are familiar from the TCP binding, but by efficiently using multiple, synchronous HTTP request/response pairs. This creative re-use of HTTP (similar to, but
subtly  different  from  the  methodology  known  as  “Comet”)  is  called  Bidirectionalstreams Over Synchronous HTTP, or BOSH for short. BOSH is defined in two specifications:  [XEP-0124]  describes  the  core  approach,  and  [XEP-0206]  describes  some
additional rules and considerations for using BOSH with XMPP systems.
180 | Chapter 12: Connection Methods and Security
BOSH-based systems are usually deployed with a special connection manager that acts
as  a  kind  of  proxy  between  the  client  and  the  XMPP  server,  as  illustrated  in  Figure 12-2. In this case, the server is a standard XMPP daemon, the connection manager
(or CM) sends XMPP to the server but HTTP to the client, and the client is a hybrid
XMPP+HTTP user agent that functions as an XMPP client from the user’s perspective
but wraps the XMPP traffic in a special <body/> element for sending to the connection
manager over HTTP.
Figure 12-2. In BOSH, the client speaks HTTP to the connection manager, which speaks XMPP to
the server
It’s Convenient, but Is It Secure?
BOSH is convenient, but because it introduces a connection manager
into the traditional XMPP architecture, it also introduces the possibility
of new attack vectors on XMPP traffic. These threats are mitigated in
several ways: the use of SSL/TLS between the client and the connection
manager, as well as between the connection manager and the XMPP
server; the large random value for the initial Request ID as described
next, inclusion of the Session ID as described below, and optional use
of a keying mechanism (not described in this chapter).
Let’s suppose that Alice finds herself behind a restrictive firewall after she falls down
the  rabbit  hole.  She  can’t  access  any  XMPP  servers  on  the  standard  port  5222,  but
maybe she can use a web client to access a BOSH connection manager being served on
port 80 or 443.
BOSH: XMPP over HTTP | 181
First, however, she needs to find the BOSH CM. She could manually configure her
client, but it is more efficient and less error-prone to use automated discovery processes.
Therefore,  her  client  sends  a  DNS  query  for  the  TXT  records  associated  with  the
wonderland.lit domain. In the DNS answer, her client finds the following record, which
matches  the  format  defined  in  Discovering  Alternative  XMPP  Connection  Methods
[XEP-0156]:
_xmppconnect IN TXT "_xmpp-client-xbosh="https://bosh.wonderland.lit/webclient"
Now that Alice’s client has found a BOSH connection manager, she can start an XMPP
session with the wonderland.lit XMPP server by sending an initial HTTP request to
https://bosh.wonderland.lit/webclient. The request consists of an HTTP POST containing a <body/> element; in this case, the element is empty, but includes a number of
attributes used to set up the BOSH session (line breaks are included for readability only,
and  the  Content-Length  is  based  on  the  XML  without  line  breaks  or  extraneous
whitespace):
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 181
<body hold="1"
      secure="true"
      rid="90029201"
      to="wonderland.lit"
      wait="60"
      xmpp:version="1.0"
      xml:lang="en"
      xmlns="http://jabber.org/protocol/httpbind"
      xmlns:xmpp="urn:xmpp:xbosh"/>
The hold attribute sets the maximum number of HTTP requests that the BOSH CM
is  allowed  to  queue  up  for  delivery  to  the  client  at  any  one  time.  Typically,  the
hold attribute is set to a value of 1, as explained later in this section.
The client includes the secure attribute with a value of true to tell the BOSH CM
that its connection to the XMPP server needs to be secure (i.e., either encrypted via
SSL/TLS or hosted on the same machine as the connection manager).
When starting a BOSH session, the client must generate a large, random number
that will function as the initial Request ID. The rid attribute is then incremented by
one with each request the client sends to the BOSH CM.
The wait attribute sets the maximum time (in seconds) that the BOSH CM is allowed
to wait before responding to a pending request; effectively this sets the timeout period for an HTTP/TCP connection.
The BOSH CM then opens a regular XMPP connection to wonderland.lit and receives
an XMPP reply (i.e., a response stream header and stream features), which it forwards
to Alice in an HTTP response:
182 | Chapter 12: Connection Methods and Security
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 390
<body hold="1" 
      requests="2"
      secure="true"
      sid="3m1ts1htd1s"
      wait="60" 
      xmpp:version="1.0"
      xmlns="http://jabber.org/protocol/httpbind"
      xmlns:stream="http://etherx.jabber.org/streams"
      xmlns:xmpp="urn:xmpp:xbosh">
  <stream:features>
    <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
      <mechanism>DIGEST-MD5</mechanism>
      <mechanism>PLAIN</mechanism>
      <required/>
    </mechanisms>
  </stream:features>
</body>
The requests attribute sets the maximum number of HTTP requests that the client
is  allowed  to  have  open  with  the  BOSH  CM  at  any  one  time.  Typically  the
requests attribute is set to a value of 2 (or, more generally, one more than the value
of the hold attribute), as explained later.
When it replies to the session creation request, the BOSH CM generates a unique
Session ID, which is different from the Stream ID generated by the XMPP server.
Each subsequent request and response must then include the sid attribute.
Alice can then authenticate with the server by sending another HTTP request whose
<body/> element contains the first step of the SASL authentication handshake (as described earlier in this chapter):
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 187
<body rid="90029202" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">
    AGFsaWNlAHBhc3N3b3JkCg==
  </auth>
</body>
The server notifies Alice of success in the HTTP response:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 127
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
</body>
BOSH: XMPP over HTTP | 183
Now that Alice has successfully authenticated with the server, she needs to restart the
stream; this is done by sending a special restart request:
POST /webclient HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 153
<body rid="90029203"
      sid="3m1ts1htd1s"
      to="wonderland.lit"
      xmpp:restart="true"
      xmlns="http://jabber.org/protocol/httpbind"
      xmlns:xmpp="urn:xmpp:xbosh"/>
The  xmpp:restart  attribute  tells  the  BOSH  CM  to  restart  the  XML  stream  it  has
opened with the XMPP server on the client’s behalf.
The connection manager restarts the stream with the XMPP server and returns a new
set of stream features:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 345
<body sid="3m1ts1htd1s" 
      xmpp:version="1.0"
      xmlns="http://jabber.org/protocol/httpbind"
      xmlns:stream="http://etherx.jabber.org/streams"
      xmlns:xmpp="urn:xmpp:xbosh">
  <stream:features>
    <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
      <required/>
    </bind>
    <session xmlns="urn:ietf:params:xml:ns:xmpp-session">
      <optional/>
    </session>
  </stream:features>
</body>
Alice now requests a resource:
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 233
<body rid="90029204" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <iq id="vc18f4hj7"
      type="set" 
      xmlns="jabber:client">
    <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
      <resource>rabbithole</resource>
    </bind>
  </iq>
</body>
184 | Chapter 12: Connection Methods and Security
The IQ stanza includes a namespace declaration because the default namespace for
BOSH is http://jabber.org/protocol/httpbind instead of the default namespace for
a client-to-server XMPP stream (i.e., jabber:client).
In response, the connection manager returns the binding result it has received from the
XMPP server:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 232
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <iq id="vc18f4hj7" type="result" xmlns="jabber:client">
    <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
      <jid>alice@wonderland.lit/rabbithole</jid>
    </bind>
  </iq>
</body>
At this point, Alice has successfully negotiated an XML stream with the XMPP server
through the BOSH CM. We assume that she also retrieves her roster and sends initial
presence (not shown here), so that she’s finally ready to communicate with people on
the network.
During the stream negotiation process, the special properties of BOSH have not yet
been revealed, because each HTTP POST sent by the client to the connection manager has
been answered almost immediately with an HTTP 200 OK containing information that
the  BOSH  CM  has  received  from  the  XMPP  server  (stream  features,  authentication
mechanisms and challenge/response combinations, IQ-set and IQ-result stanzas related to resource binding and roster retrieval, and initial presence). These interactions all
happen within the timeout period that is set by the value of the wait attribute (in this
case, 60 seconds).
The real usefulness of BOSH comes into the picture when Alice does not send or receive
a stanza for longer than the timeout period. When that happens, the connection manager will send keepalives to Alice if the timeout period is about to expire, or will return
an empty body element to her if she has more than one HTTP request pending at a
time. For instance, in our scenario, Alice has told the BOSH CM that she wants it to
hold onto at most one HTTP request at a time (hold=1), and the CM has replied that
it will let Alice have at most two HTTP requests in play at a time (requests=2). Because
the timeout period is one minute (wait=60), if Alice has not received an HTTP response
to her first request within 60 seconds (usually because the BOSH CM has not received
any incoming stanzas for her), then the CM will return an HTTP 200 OK response containing an empty <body/> element. This response functions as a keepalive. If Alice does
not have any outbound stanzas to send at this point, then her client sends an HTTP
request that also contains an empty <body/> element.
Alice and the CM can keep sending these keepalives every 60 seconds until one of the
following happens:
BOSH: XMPP over HTTP | 185
• The BOSH CM receives an incoming stanza for Alice, at which point, the CM will
return an HTTP 200 OK response to her with a nonempty <body/> element that contains the incoming stanza.
• Alice sends another outbound stanza, at which point, she will have two HTTP
requests in play, thus forcing the connection manager to respond to her first HTTP
request with an HTTP 200 OK response containing an empty <body/> element.
This approach is illustrated in Figure 12-3.
Let’s see how these interactions happen in protocol.
First, Alice sends a message to her sister:
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 205
<body rid="90029205" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message to="sister@realworld.lit" xmlns="jabber:client">
    <body>Help, I fell down the rabbit hole!</body>
  </message>
</body>
Here we assume that Alice does not yet receive an immediate HTTP response from the
connection manager because it takes half a minute for Alice’s sister to notice the message and then reply. The connection manager therefore delays sending an HTTP response until it receives data intended for delivery to Alice. Because this delay does not
quite approach the timeout period, the BOSH CM returns a nonempty <body/> element
that contains the reply from her sister:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 163
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message from="sister@realworld.lit/home">
    <body>Oh my! How can I help?</body>
  </message>
</body>
Alice quickly replies by sending a new HTTP POST to the CM (thus she once again has
one HTTP request in play):
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 206
<body rid="90029206" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message to="sister@realworld.lit/home">
    <body>I don't know yet, it's all very confusing!</body>
  </message>
</body>
186 | Chapter 12: Connection Methods and Security
Figure  12-3.  BOSH  uses  multiple  HTTP  request/response  pairs  to  emulate  a  bidirectional  TCP
connection
And Alice’s sister just as quickly replies:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 194
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
BOSH: XMPP over HTTP | 187
  <message from="sister@realworld.lit/home">
    <body>I'm going to find mother, but I'll be back!</body>
  </message>
</body>
Alice thanks her sister and anxiously awaits a reply:
POST /webclient HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 161
<body rid="90029207" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message to="sister@realworld.lit/home">
    <body>Thanks!</body>
  </message>
</body>
Alice now has one HTTP request in play. Now, however, Alice’s sister has run off to
find their mother, so Alice does not receive a reply from her sister within the timeout
period. The connection manager therefore tells Alice that it hasn’t received any incoming stanzas for her, by returning an HTTP response with an empty <body/> element. It
does this because it is not allowed to hold on to the request longer than the timeout
period set in the wait attribute, i.e., 60 seconds. This empty response functions as a
keepalive:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 70
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind"/>
Because Alice has not generated any more outbound stanzas, her client immediately
sends an HTTP request that also contains an empty <body/> element, thus putting the
BOSH CM on notice that she is still interested in receiving incoming stanzas:
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 85
<body rid="90029208" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind"/>
However, Alice is getting nervous, so before the next timeout period expires, she sends
another HTTP request containing an outbound stanza:
POST /webclient HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 167
<body rid="90029209" sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message to="sister@realworld.lit/home">
    <body>Please hurry!</body>
  </message>
</body>
188 | Chapter 12: Connection Methods and Security
Alice now has two HTTP requests in play, so she has hit the limit set by the requests
attribute. The BOSH CM therefore sends a reply to her first HTTP POST (the empty
one). In this case, the response also contains an empty <body/> element, because the
connection manager has not yet received any incoming stanzas for Alice:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 70
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind"/>
After a short while (less than the timeout period related to the second request), Alice’s
sister finally responds. As a result, the connection manager sends an HTTP response
to the last (nonempty) HTTP POST:
POST /webclient HTTP/1.1
Host: bosh.wonderland.lit
Content-Type: text/xml; charset=utf-8
Content-Length: 163
<body sid="3m1ts1htd1s" xmlns="http://jabber.org/protocol/httpbind">
  <message from="sister@realworld.lit/home">
    <body>She's on her way!</body>
  </message>
</body>
As you can see, by having only two request-response pairs outstanding at any one time,
and embedding incoming XMPP stanzas in responses to outgoing HTTP requests sent
from the client, BOSH can neatly map XMPP’s bidirectional streams to HTTP semantics. Best of all, it achieves this efficiency without forcing the client to constantly poll
the connection manager. Exactly how efficient BOSH turns out to be depends on the
values of the hold, requests, and wait attributes.
BOSH and Constrained Clients
In constrained clients that cannot maintain two request-response pairs,
the client can ask the connection manager to have only one requestresponse pair outstanding at a time. However, this method means that
the connection manager always responds immediately to every request
and that it is the responsibility of the client to check for incoming XMPP
stanzas at regular intervals (by sending empty <body/> elements). As a
result, this message is much less efficient, although still a viable alternative to long-lived TCP connections.
Serverless Messaging
XMPP is based on a client-server architecture, which means that you always need a
server if you want to communicate between two people. Thanks to the widespread
deployment of Internet connectivity in many parts of the world, connecting to a server
to  communicate  via  XMPP  rarely  is  a  problem.  However,  in  some  less  fortunate
Serverless Messaging | 189
situations, connecting to an XMPP server can pose a problem. The following are some
examples:
• You might be in a remote location that has no Internet connectivity (say, a rural
school), but you still want to use XMPP to communicate with other people in the
area.
• You might be at an international conference where you want to discuss the topic
of the current talk with the people in the room, but you don’t know their JabberIDs.
• You might have fallen down a rabbit hole, and the authorities there block all out
bound connections to the Internet!
Indeed, this problem is not limited to XMPP. For example, you might want to find local
devices such as printers without any central coordination. However, the problem is
more acute in XMPP because it is almost always deployed using a client-server architecture.  To  solve  the  more  general  problem,  a  team  of  people  at  Apple  Computer
defined a set of technologies known as “zero-configuration networking.” These technologies in turn have been applied to real-time communication using XMPP, and this
usage  has  been  standardized  by  the  XSF  under  the  name  Serverless  Messaging
[XEP-0174].
Picture poor Alice and her friends down the rabbit hole when the queen exclaims, “Off
with their net!” and blocks connections to the broader Internet. How will they communicate? It turns out that there’s still a local network in Wonderland, so maybe they
can use that for communication. To do so, Alice needs to discover who is on the local
network and to ensure that the others can find her there.
The basic approach is that each person will multicast special DNS entries to everyone
on  the  local  network;  as  a  result,  they  will  collectively  manage  a  reserved  top-level
domain called .local. For the sake of serverless messaging, we are not interested in all
of the services that might exist on the .local domain (printers and the like), but only
in entities that advertise support for the presence service using defined DNS PTR, A,
and SRV records. (For all the details, refer to the Multicast DNS [mDNS] and DNSbased service discovery [DNS-SD] specifications.)
To find her friends on the local network, Alice would first broadcast a multicast DNS
query for all PTR records that match the _presence._tcp.local. service. Anyone on the
local network can answer this query; down the rabbit hole, this query will result in
answers like the following:
_presence._tcp.local. PTR hatter@mercury._presence._tcp.local.
_presence._tcp.local. PTR rabbit@ivory._presence._tcp.local.
Here, Alice finds two people on the local network: the Mad Hatter (who is the user
hatter on a machine named mercury) and the White Rabbit (who is the user rabbit on
a machine named ivory). Let’s say that she wants to chat with the Mad Hatter. She has
a pointer to his machine, but she needs to find out the hostname and port number of
190 | Chapter 12: Connection Methods and Security
this machine (mercury). So, she broadcasts another mDNS query, requesting the SRV
record of the hatter@mercury presence service. This returns the following information:
hatter@mercury._presence._tcp.local. SRV 5562 mercury.local.
Now Alice knows that the XMPP client for hatter@mercury is listening on port 5562 of
the host mercury.local. The final piece of the puzzle is finding out the actual IP address
of mercury.local. This is done by broadcasting an mDNS query for the A (or, for IPv6,
the AAAA) DNS record of that hostname; the answer is as follows:
mercury.local. A 10.2.1.187
At this point, Alice knows exactly where to connect for starting her XMPP conversation
with the Mad Hatter. All of this DNS magic has simply been a precursor to XMPP
communications!  To  chat  with  the  Mad  Hatter,  Alice  opens  a  TCP  connection  to
10.2.1.187 on port 5562 and starts an XMPP stream:
<stream:stream from="alice@odyssey" 
               to="hatter@mercury"
               version="1.0"
               xmlns="jabber:client" 
               xmlns:stream="http://etherx.jabber.org/streams">
The Mad Hatter responds by opening an XMPP stream back to Alice at the IP address
and port she has advertised:
<stream:stream from="hatter@mercury" 
               to="alice@odyssey"
               version="1.0"
               xmlns="jabber:client" 
               xmlns:stream="http://etherx.jabber.org/streams">
After this handshake, Alice can send <message/> and <iq/> stanzas back and forth to
start her conversation, just as she would over a normal XMPP connection. (There is no
TLS encryption or SASL authentication for these serverless streams, although methods
for doing so are in the works to improve the security of ad-hoc meshes.)
<message from="alice@odyssey" to="hatter@mercury">
  <body>I didn't know it was YOUR table; it's laid for a great many more than 
  three.</body>
</message>
Besides knowing the machines on the network, Alice would also like to find out more
detailed information about the people (or fictional characters) behind those machines.
This information is also stored in mDNS records, specifically in DNS TXT records that
contain a variety of key-value pairs. For example, a request for the Mad Hatter’s TXT
record might result in the following response:
hatter@mercury._presence._tcp.local. IN TXT "
  txtvers=1
  status=avail
  msg=Having a spot of tea
  1st=Mad
  last=Hatter
Serverless Messaging | 191
  nick=thehatter
  node=http://psi-im.org/caps
  ver=QgayPKawpkPSDYmwT/WM94uAlu0=
  hash=sha-1
  
This version number is always 1, and the txtvers field must always come first in the
TXT record value.
This is equivalent to the <show/> element from standard XMPP presence, except that
mere available presence is mapped to a TXT show of avail.
This is equivalent to the <status/> element from standard XMPP presence.
This is equivalent to the node attribute from the XMPP Entity Capabilities extension.
This is equivalent to the ver attribute from the XMPP Entity Capabilities extension.
This is equivalent to the hash attribute from the XMPP Entity Capabilities extension.
Besides presence information, Alice also received some basic information about the
Mad  Hatter’s  identity  and  the  capabilities  of  his  client  (as  described  in  Chapter  5).
Whenever  the  Mad  Hatter  updates  his  presence  information  (by  publishing  a  new
TXT record), it will be broadcast on the network, notifying everybody of the change.
So far, Alice has discovered and connected to other clients on the network. Of course,
she also needs to announce her own XMPP client to the other clients, so that they can
contact her as well. She does this by publishing the same types of mDNS and DNS-SD
records that she used to discover the other clients:
odyssey.local. A 10.2.1.188
_presence._tcp.local. PTR alice@odyssey._presence._tcp.local.
alice@odyssey._presence._tcp.local. SRV 5562 odyssey.local. 
alice@odyssey._presence._tcp.local. IN TXT "txtvers=1
  status=avail
  1st=Alice"
Serverless messaging provides yet another way to use the same XMPP “primitives” in
ways that expand the ability to communicate (even when there is no server in the mix).
Future topics in the area of serverless messaging include encryption and authentication
using TLS and SASL, as well as the ability to seamlessly bridge between the serverless
mode and the traditional client-server mode for improved connections between local
meshes and the broader network.
XMPP Security
Everyone says that they like to use secure technologies, but few people rigorously define
security—and even fewer do the hard work necessary to make communication systems
both secure and usable. Security can mean different things to different people, but there
is general agreement among security professionals that the most common threats to
communication systems include the following:
192 | Chapter 12: Connection Methods and Security
• Eavesdropping on communication channels
• Unauthenticated or weakly authenticated users
• Rogue servers
• Address spoofing
• Denial of service attacks
• Viruses, worms, and other malware
• Unwanted communications (“spam”)
• Impersonation attacks (“phishing”)
• Leaks of personal or privileged information
• Inappropriate logging or archiving
• Buffer overflows and other code security issues
Before you deploy an XMPP application, it’s important to understand the track record
of XMPP technologies on these critical issues. The good news is that the attacks we
discuss here are, so far, mostly theoretical. Even the open XMPP network running on
the public Internet since 1999 has experienced very few security issues: no significant
denial  of  service  attacks;  very  little  spam;  no  known  instances  of  phishing,  viruses,
worms, or other malware; no rogue servers; and only a few code security reports related
to particular clients and servers (which were quickly fixed in most cases).
However, the lack of successful attacks is no reason to be complacent. Because information security is a bit of an “arms race” between the bad guys and the good guys, the
XMPP community continues to work on ways to prevent these attacks (and others that
might arise in the future). So let’s look at what XMPP technologies have to offer in the
area of security. We can’t discuss every possible threat in this book, but the following
topics should give you a feeling for the approaches taken by both developers and operators in the XMPP community. (If you have a strong interest in security issues, be
sure to join the security@xmpp.org discussion list.)
Encryption
Earlier  in  this  chapter,  we  discussed  the  use  of  Transport  Layer  Security  (TLS)  for
channel encryption. This technology is mandatory to implement for XMPP servers and
clients. It is also widely (but not yet universally) deployed by operators of XMPP-based
services. The use of TLS overcomes many concerns about the identity of servers on the
network and makes it straightforward to encrypt traffic on client-to-server and serverto-server links.
Channel encryption is good, but it leaves a few vulnerable points. Even if you encrypt
your connection to your server, your contact encrypts her connection to her server, and
the link between the two servers is also encrypted, the messages that you exchange with
your friend are still unencrypted inside the servers themselves. This means that the
server admins could be logging all of your messages as they pass through. Not good!
XMPP Security | 193
The solution is called end-to-end encryption, whereby you and your friend negotiate a
method for encrypting your messages so that no one in the middle can read them.
However, end-to-end encryption is a hard problem. The approach taken by the early
open source developers was to use the open flavor of Pretty Good Privacy (PGP), called
OpenPGP. Unfortunately, typical end users don’t have PGP keys. The approach recommended by various IETF security experts during formalization of XMPP was to use
Secure/Multipurpose Internet Mail Extensions (S/MIME), but this approach has never
taken off in the XMPP community (partly because the resulting technology was not
very “Jabberish” and partly because it required users to have digital certificates, which
are probably even less common than PGP keys). Another interim technology, Encrypted Sessions, is supported in one open source XMPP client, but its security properties
have not been fully validated, and it too is seen as difficult to implement by most developers. The community is currently working on an adaptation of Transport Layer
Security that can be exchanged between clients over XMPP, but work on it is not complete as of this writing. Visit http://xmpp.org for up-to-date information about end-toend encryption.
Authentication and Identity
Perhaps the most basic form of trust on a communications network is knowing that
the sender of a message is who he says he is. If addresses can be faked or users can be
impersonated, trust quickly breaks down and people migrate to a different communications technology.
XMPP  includes  a  number  of  methods  for  ensuring  relatively  strong  identity  on  the
network. One such method is authentication: a server will not allow users onto the
network unless they first provide proper credentials during the login process. Unless a
user’s password or other credential information is leaked, the authentication requirement almost guarantees that the person you added to your contact list yesterday or last
year is the same person today. In addition, XMPP servers do not allow end users to
assert just any “from” address on the stanzas they send; instead, the “from” address is
always stamped by the user’s server, further strengthening trust in the messages you
receive.
Another aspect of identity and authentication relates to domain names. As we discussed
earlier in this chapter, XMPP server instances are also checked in inter-domain communication, either via the server dialback protocol or TLS plus SASL (which provide
weak and strong identity verification, respectively). Servers are also required to verify
incoming  stanzas  from  other  domains,  so  that,  say,  the  wonderland.lit  server  can’t
masquerade as looking-glass.lit. These rules help to prevent faked addresses on the
network. These relatively strong identities can also be bootstrapped into trust islands
by means of blacklisting and whitelisting other domains, either at the firewall or in
XMPP server software.
194 | Chapter 12: Connection Methods and Security
That said, the use of the full Unicode character set for JabberIDs introduces the possibility of some impersonation attacks, because characters in different scripts can look
very much alike. A very simple method that can be implemented even in plain ASCII
addresses is to replace the letter “l” with the number “1”, as in paypa1.com (which has
been known to fool end users). When an address can include different characters that
are effectively indistinguishable—such as “a” (Latin Small Letter A) and “а” (Cyrillic
Small Letter A)— the potential for abuse is significant. For this reason, XMPP clients
are encouraged to handle mixed-character addresses carefully.
Spam and Abuse
Every communication system can be a breeding ground for unsolicited bulk messages
(“spam”) and other forms of abuse. It is currently estimated that 90% or more of the
email messages sent over the Internet are spam. What has the XMPP community done
to prevent spam from taking over its network?
On the face of it, the fact that XMPP is a distributed technology (just like email) and
not a centralized service (like most legacy instant messaging systems) might make you
think that the XMPP network would be open to the same kinds of spam threats as the
email network. However, there are some important differences:
• Most people assume that you must be able to send an email to any random person
on the Internet. Techniques that require you to be authorized before you can send
someone an email message are viewed with suspicion. Yet the very same system
exists in IM—we call it a roster—without offending anyone. In XMPP, we can
leverage presence subscriptions to block messages from anyone who is not in your
roster, cutting down on spam quite a bit.
• Spam is not just an annoyance: it’s a business. If it is more expensive for spammers
to operate on the XMPP network than on, say, the email network, they will tend
to stay on the email network. XMPP developers and operators continue to raise
the bar for participation; for example, they might require digital certificates from
trusted CA’s at some point in the next few years, and those certificates could be
easily revoked from domains that behave badly on the network.
• Spammers  send  a  lot  of  messages.  However,  all  XMPP  server  daemons  include
built-in rate limiting, which prevents users from sending a large volume of messages
in a short period of time. True, a spammer could get around this restriction by
creating a large number of accounts on a particular server, but servers could restrict
registration by requiring CAPTCHAs or other techniques for account registration
(as described in Chapter 6) and by limiting the number of registration attempts per
IP address. Yet XMPP is a distributed technology, so spammers could create accounts on multiple servers, thus forcing administrators of legitimate XMPP servers
to work together on blocking techniques (e.g., maintaining a repository of blacklisted domains or IP addresses). And so the arms race continues. For some related
XMPP Security | 195
recommendations for server administrators, see Best Practices to Discourage Denial
of Service Attacks [XEP-0205].
Summary
Whereas  in  previous  chapters,  we  explored  higher-level  XMPP  extensions,  in  this
chapter, we delved into the fundamentals: XML streams, TCP and HTTP connection
methods, channel encryption via Transport Layer Security (TLS), the authentication
framework provided through the Simple Authentication and Security Layer (SASL),
dynamic  federation  of  XMPP  servers  using  the  Server  Dialback  protocol,  serverless
messaging, and key considerations related to the security of XMPP systems. Depending
on the type of application you want to build, you may not need to worry about these
lower layers of the XMPP stack. However, it is good to know that you have flexibility
here, too.
196 | Chapter 12: Connection Methods and Security
PART III
Putting It All Together
